#ifndef _SAFETY_BOARD_H_
#define _SAFETY_BOARD_H_

#include <config.h>
#include <stdbool.h>
#include "face_app.h"
#include "finger_app.h"

#if _SAFETY_VERIFYFUNCTION_ENABLE_

#if _BOARD_TYPE_ == _V31_A_BOARD_
// 外部安全模组串口接收
#define SAFETY_UART_RXD_PIN                    GPIO_Pin_4
// 外部安全模组串口发送
#define SAFETY_UART_TXD_PIN                    GPIO_Pin_5
// 外部安全模组中断管脚
#define SAFETY_EVENT_IRQN_PIN                  GPIO_Pin_0
// 外部安全模组电源控制管脚
#define SAFETY_POWER_CONTORL_PIN               GPIO_Pin_6

#elif _BOARD_TYPE_ == _V33_A_BOARD_
// 外部安全模组串口接收
#define SAFETY_UART_RXD_PIN                    GPIO_Pin_4
// 外部安全模组串口发送
#define SAFETY_UART_TXD_PIN                    GPIO_Pin_5
// 外部安全模组中断管脚
#define SAFETY_EVENT_IRQN_PIN                  GPIO_Pin_6
// 外部安全模组电源控制管脚
#define SAFETY_POWER_CONTORL_PIN               GPIO_Pin_0

#elif _BOARD_TYPE_ == _V33_B_BOARD_
// 外部安全模组串口接收
#define SAFETY_UART_RXD_PIN                    GPIO_Pin_20
// 外部安全模组串口发送
#define SAFETY_UART_TXD_PIN                    GPIO_Pin_21
// 外部安全模组中断管脚
#define SAFETY_EVENT_IRQN_PIN                  GPIO_Pin_5
// 外部安全模组电源控制管脚
#define SAFETY_POWER_CONTORL_PIN               GPIO_Pin_19

#elif _BOARD_TYPE_ == _V33_C_BOARD_
// 外部安全模组串口接收
#define SAFETY_UART_RXD_PIN                    GPIO_Pin_15
// 外部安全模组串口发送
#define SAFETY_UART_TXD_PIN                    GPIO_Pin_14
// 外部安全模组中断管脚
#define SAFETY_EVENT_IRQN_PIN                  GPIO_Pin_3
// 外部安全模组电源控制管脚
#define SAFETY_POWER_CONTORL_PIN               GPIO_Pin_13
#endif

// 串口波特率
#if _SAFETY_MODULE_TYPE_ == _FACE_SAFETY_MODULE_
#define SAFETY_UART_BAUD_RATE                  (115200ul)

#elif _SAFETY_MODULE_TYPE_ == _FINGER_SAFETY_MODULE_
#define SAFETY_UART_BAUD_RATE                  (57600ul)
#endif

// 收发报文长度
#define SAFETY_MESSAGE_PACKET_LENGTH           (NOMINAL_PACKET_LENGTH)

/**
 * @brief 命令执行结果
 *
 */
typedef enum
{
  SAFETY_COMMAND_ERROR,               // 错误
  SAFETY_COMMAND_SUCCESS,             // 成功
  SAFETY_COMMAND_USER_IS_FULL,        // 用户已满
  SAFETY_COMMAND_USER_ALREADY_EXISTS, // 用户已存在
} SafetyCommandExecuteResult_t;

/**
 * @brief 事件执行状态
 *
 */
typedef enum
{
#if _SAFETY_MODULE_TYPE_ == _FACE_SAFETY_MODULE_
  SAFETY_MESSAGE_EXECUTE_OVER                = FACE_EXECUTE_OVER,                // 完毕
  SAFETY_MESSAGE_EXECUTE_WAIT                = FACE_EXECUTE_WAIT,                // 等待
  SAFETY_MESSAGE_EXECUTE_ERROR               = FACE_EXECUTE_ERROR,               // 错误
  SAFETY_MESSAGE_EXECUTE_RETRY               = FACE_EXECUTE_RETRY,               // 重试
  SAFETY_MESSAGE_EXECUTE_SUCCESS             = FACE_EXECUTE_SUCCESS,             // 成功
  SAFETY_MESSAGE_EXECUTE_USER_IS_FULL        = FACE_EXECUTE_USER_IS_FULL,        // 用户已满
  SAFETY_MESSAGE_EXECUTE_USER_ALREADY_EXISTS = FACE_EXECUTE_USER_ALREADY_EXISTS, // 用户已存在

#elif _SAFETY_MODULE_TYPE_ == _FINGER_SAFETY_MODULE_
  SAFETY_MESSAGE_EXECUTE_OVER                = FINGER_EXECUTE_OVER,                // 完毕
  SAFETY_MESSAGE_EXECUTE_WAIT                = FINGER_EXECUTE_WAIT,                // 等待
  SAFETY_MESSAGE_EXECUTE_ERROR               = FINGER_EXECUTE_ERROR,               // 错误
  SAFETY_MESSAGE_EXECUTE_RETRY               = FINGER_EXECUTE_RETRY,               // 重试
  SAFETY_MESSAGE_EXECUTE_SUCCESS             = FINGER_EXECUTE_SUCCESS,             // 成功
  SAFETY_MESSAGE_EXECUTE_USER_IS_FULL        = FINGER_EXECUTE_USER_IS_FULL,        // 用户已满
  SAFETY_MESSAGE_EXECUTE_USER_ALREADY_EXISTS = FINGER_EXECUTE_USER_ALREADY_EXISTS, // 用户已存在

#else
  SAFETY_MESSAGE_EXECUTE_OVER,                // 完毕
  SAFETY_MESSAGE_EXECUTE_ERROR,               // 错误
  SAFETY_MESSAGE_EXECUTE_RETRY,               // 重试
  SAFETY_MESSAGE_EXECUTE_SUCCESS,             // 成功
  SAFETY_MESSAGE_EXECUTE_USER_IS_FULL,        // 用户已满
  SAFETY_MESSAGE_EXECUTE_USER_ALREADY_EXISTS, // 用户已存在
#endif
} SafetyMessageExecuteResult_t;

/**
 * @brief 事件服务类型
 *
 */
typedef enum
{
  SAFETY_COMMAND_OPERATION = 1 << 0, // 数据操作
} SafetyEventTask_t;

// 串口接收完毕
typedef void (*SafetyUartRxDone_t)(void);
// 事件唤醒
typedef void (*SafetyEventWakeup_t)(void);
// 数据操作
typedef void (*SafetyCommandOperation_t)(void);

// 报文构建
typedef bool (*SafetyMessageSending_t)(uint8_t *, uint16_t *, uint32_t *);
// 报文解析
typedef uint8_t (*SafetyMessageParsing_t)(const void *, uint16_t, uint8_t);

/**
 * @brief 收发数据包
 *
 */
typedef struct
{
  uint16_t DataSize;                              // 数据长度
  uint8_t DataBuff[SAFETY_MESSAGE_PACKET_LENGTH]; // 收发数据流
} SafetyDataPacket_t;

/**
 * @brief 设备自检命令接口表
 *
 */
typedef struct
{
  SafetyMessageSending_t Build;   // 发送发送
  SafetyMessageParsing_t Parsing; // 解析方法
} SafetyCommandApiTable_t;

/**
 * @brief 任务相关接口
 *
 */
typedef struct
{
  SafetyCommandApiTable_t SelfTestCallback;                 // 自检服务
  SafetyCommandApiTable_t FactorySettingCallback;           // 恢复出厂
  SafetyCommandApiTable_t ForcedToGotoSleepCallback;        // 睡眠回调
  SafetyCommandApiTable_t GetEigenvalueFileCallback;        // 获取特征值文件
  SafetyCommandApiTable_t LocalRegisterUserCallback;        // 本地注册用户
  SafetyCommandApiTable_t IdentifyUserRightsCallback;       // 鉴定用户权限
  SafetyCommandApiTable_t DeletingSpecificUsersCallback;    // 删除特定用户
  SafetyCommandApiTable_t RegistrationByEigenvalueCallback; // 通过特征值注册用户
} SafetyTaskApi_t;

/**
 * @brief 外部调用方法
 *
 */
typedef struct
{
  SafetyUartRxDone_t UartRxDoneCallBack;             // 串口接收完毕回调
  SafetyEventWakeup_t EventWakeupCallback;           // 事件唤醒回调
  SafetyCommandOperation_t CommandOperationCallback; // 命令操作回调
} SafetyExternFunctionTable_t;

/**
 * @brief 毫秒延时
 *
 * @param Ms - 延时时间
 */
extern void SafetyDelayMs(uint16_t Ms);

/**
 * @brief 设置电源控制管脚电平
 *
 * @param PinLevel - 管脚电平
 */
extern void SafetySetPowerContorlPinLevel(bool PinLevel);

/**
 * @brief 获取中断管脚电平
 *
 * @return bool - 管脚电平（true：高电平 false：低电平）
 */
extern bool SafetyGetIrqnPinLevel(void);

/**
 * @brief 通过串口向外部验证模组发送一定数据长度的数据
 *
 * @param pDataIn - 待发送的数据流
 * @param SizeIn  - 发送数据长度
 * @return bool   - 发送状态（true：成功 false：失败）
 */
extern bool SafetyUartSendData(uint8_t *pDataIn, uint16_t SizeIn);

/**
 * @brief 获取已注册用户数量
 *
 * @return uint8_t - 已注册用户数量
 */
extern uint8_t SafetyGetTheNumberOfRegisteredUsers(void);

/**
 * @brief 获取设备序列号
 *
 * @param pSerialNumberOut - 设备序列号
 */
extern void SafetyGetDeviceSerialNumber(char *pSerialNumberOut);

/**
 * @brief 获取固件版本号
 *
 * @param pVersionOut - 固件版本号
 */
extern void SafetyGetApplicationVersion(char *pVersionOut);

/**
 * @brief 获取算法版本号
 *
 * @param pVersionOut - 固算法版本号
 */
extern void SafetyGetAlgorithmVersion(char *pVersionOut);

/**
 * @brief 上报自检结果
 *
 * @param Result - 自检结果
 */
extern void SafetyReportgSeltTestResult(SafetyCommandExecuteResult_t Result);

/**
 * @brief 告知重置结果
 *
 * @param Result - 结果
 */
extern void SafetyNotificationResetResults(SafetyCommandExecuteResult_t Result);

/**
 * @brief 告知获取特征值文件结果
 *
 * @param Result - 获取结果
 * @return bool  - 状态（true：成功 false：失败）
 */
extern bool SafetyNotificationGetEigenvalueFileResult(SafetyCommandExecuteResult_t Result);

/**
 * @brief 上报本地注册密钥结果
 *
 * @param Result - 本地注册结果
 * @return bool  - 上报状态（true：成功 false：失败）
 */
extern bool SafetyReportLocalRegisterKeyResult(SafetyCommandExecuteResult_t Result);

/**
 * @brief 上报在线注册密钥结果
 *
 * @param Result - 在线注册结果
 * @return bool  - 上报状态（true：成功 false：失败）
 */
extern bool SafertReportOnlineRegisterKeyResult(SafetyCommandExecuteResult_t Result);

/**
 * @brief 上报模组鉴权结果
 *
 * @param Result - 本地注册结果
 * @return bool  - 上报状态（true：成功 false：失败）
 */
extern bool SafetyReportUserAuthenticationResult(SafetyCommandExecuteResult_t Result);

/**
 * @brief 退出在线注册用户任务
 *
 */
extern void SafetyExitOnlineRegisterListerTask(void);

/**
 * @brief 通讯初始化
 *
 */
extern void SafetyCommunicationsInitialization(void);

/**
 * @brief 初始化强制进入睡眠
 *
 */
extern void SafetyForcedToGotoSleepInitialization(void);

/**
 * @brief 启动本地注册用户
 *
 * @param WaitTime - 等待时间
 */
extern void SafetyStartLocalRegisterTask(uint8_t WaitTime);

/**
 * @brief 启动用户鉴权
 *
 */
extern void SafetyStartAuthenticationTask(void);

/**
 * @brief 标记目标用户以获取特征值文件
 *
 * @param UserId - 待获取的用户编码
 */
extern void SafetyFlaggingTargetUsersToGetFeatureValueFiles(uint16_t UserId);

/**
 * @brief 删除用户前的准备
 *
 */
extern void SafetyPreparationBeforeDeletingUser(void);

/**
 * @brief 记录待删除的用户
 *
 * @param UserId - 待删除的用户
 */
extern void SafetyRecordUsersToBeDeleted(uint16_t UserId);

/**
 * @brief 验证报文有效性
 *
 * @param pMessageIn     - 待验证报文
 * @param pDataOffsetOut - 指向附带数据起始地址的指针变量
 * @param pDataSizeOut   - 附带数据长度
 * @param pResultOut     - 影响结果
 * @return bool          - 验证状态（true：成功 false：失败）
 */
extern bool SafetyVerifyMessageValidity(uint8_t *pMessageIn, uint8_t *pDataOffsetOut, uint16_t *pDataSizeOut, uint8_t *pResultOut);

/**
 * @brief 使能中断
 *
 */
extern void SafetyEnableInterrupts(void);

/**
 * @brief 失能中断
 *
 */
extern void SafetyDisableInterrupts(void);

/**
 * @brief 配置低功耗模式
 *
 */
extern void SafetyConfigurationLowPower(void);

/**
 * @brief 配置为正常模式
 *
 */
extern void SafetyConfigurationNormalMode(void);

/**
 * @brief 停止命令操作任务
 *
 */
extern void SafetyStopCommandOperationTask(void);

/**
 * @brief 延时启动命令操作任务
 *
 * @param Ms - 延时的时间
 */
extern void SafetyDelayedStartCommandOperationTask(uint32_t Ms);

/**
 * @brief 立即启动命令操作任务
 *
 */
extern void SafetyStartCommandOperationTaskNoWait(void);

/**
 * @brief 板载功能初始化
 *
 * @param pTaskApiOut       - 事件接口
 * @param pDataPacketIn     - 数据收发缓存区
 * @param pExternFunctionIn - 外部调用方法
 */
extern void SafetyBoardBoardInitialisation(SafetyTaskApi_t *pTaskApiOut, SafetyDataPacket_t *pDataPacket, SafetyExternFunctionTable_t *pExternFunctionIn);

#endif
#endif
